package input;

import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.util.vector.Vector3f;

public class Controller {

    private final int MAX_LOOK_DOWN = -85;
    private final int MAX_LOOK_UP = 85;
    
	public double x, z, xa, za, rotationA;

	public Vector3f rotation = new Vector3f(0, 0, 0);
	public Vector3f position = new Vector3f(0, 0, 0);

	private int mouseSpeed = 1;
	private int walkingSpeed = 20;
	//private double jumoHeight = 5;
	private long lastFrame;
	
	//private int time = 0;

	public void tick() {
		
		//time++;
		
		int delta = getDelta();

		boolean keyUp = Keyboard.isKeyDown(Keyboard.KEY_W);
		boolean keyDown = Keyboard.isKeyDown(Keyboard.KEY_S);
		boolean keyLeft = Keyboard.isKeyDown(Keyboard.KEY_A);
		boolean keyRight = Keyboard.isKeyDown(Keyboard.KEY_D);
		boolean flyUp = Keyboard.isKeyDown(Keyboard.KEY_SPACE);
		boolean flyDown = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT);
		boolean moveFaster = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL);
		boolean moveSlower = Keyboard.isKeyDown(Keyboard.KEY_TAB);
		boolean jump = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL);

		if (moveFaster && !moveSlower) {
			walkingSpeed *= 4f;
		}
		if (moveSlower && !moveFaster) {
			walkingSpeed /= 10f;
		}

		if (keyUp && keyRight) {
			float angle = rotation.y + 45;
			Vector3f newPosition = new Vector3f(position);
			float oblique = (walkingSpeed * 0.0002f) * delta;
			float adjacent = oblique * (float) Math.cos(Math.toRadians(angle));
			float opposite = (float) (Math.sin(Math.toRadians(angle)) * oblique);
			newPosition.z += adjacent;
			newPosition.x -= opposite;
			position.z = newPosition.z;
			position.x = newPosition.x;
		}
		if (keyUp && keyLeft) {
			float angle = rotation.y - 45;
			Vector3f newPosition = new Vector3f(position);
			float oblique = (walkingSpeed * 0.0002f) * delta;
			float adjacent = oblique * (float) Math.cos(Math.toRadians(angle));
			float opposite = (float) (Math.sin(Math.toRadians(angle)) * oblique);
			newPosition.z += adjacent;
			newPosition.x -= opposite;
			position.z = newPosition.z;
			position.x = newPosition.x;
		}
		if (keyUp) {
			float angle = rotation.y;
			Vector3f newPosition = new Vector3f(position);
			float oblique = (walkingSpeed * 0.0002f) * delta;
			float adjacent = oblique * (float) Math.cos(Math.toRadians(angle));
			float opposite = (float) (Math.sin(Math.toRadians(angle)) * oblique);
			newPosition.z += adjacent;
			newPosition.x -= opposite;
			position.z = newPosition.z;
			position.x = newPosition.x;
		}
		if (keyDown && keyLeft) {
			float angle = rotation.y - 135;
			Vector3f newPosition = new Vector3f(position);
			float oblique = (walkingSpeed * 0.0002f) * delta;
			float adjacent = oblique * (float) Math.cos(Math.toRadians(angle));
			float opposite = (float) (Math.sin(Math.toRadians(angle)) * oblique);
			newPosition.z += adjacent;
			newPosition.x -= opposite;
			position.z = newPosition.z;
			position.x = newPosition.x;
		}
		if (keyDown && keyRight) {
			float angle = rotation.y + 135;
			Vector3f newPosition = new Vector3f(position);
			float oblique = (walkingSpeed * 0.0002f) * delta;
			float adjacent = oblique * (float) Math.cos(Math.toRadians(angle));
			float opposite = (float) (Math.sin(Math.toRadians(angle)) * oblique);
			newPosition.z += adjacent;
			newPosition.x -= opposite;
			position.z = newPosition.z;
			position.x = newPosition.x;
		}
		if (keyDown) {
			float angle = rotation.y;
			Vector3f newPosition = new Vector3f(position);
			float oblique = -(walkingSpeed * 0.0002f) * delta;
			float adjacent = oblique * (float) Math.cos(Math.toRadians(angle));
			float opposite = (float) (Math.sin(Math.toRadians(angle)) * oblique);
			newPosition.z += adjacent;
			newPosition.x -= opposite;
			position.z = newPosition.z;
			position.x = newPosition.x;
		}
		if (keyLeft) {
			float angle = rotation.y - 90;
			Vector3f newPosition = new Vector3f(position);
			float oblique = (walkingSpeed * 0.0002f) * delta;
			float adjacent = oblique * (float) Math.cos(Math.toRadians(angle));
			float opposite = (float) (Math.sin(Math.toRadians(angle)) * oblique);
			newPosition.z += adjacent;
			newPosition.x -= opposite;
			position.z = newPosition.z;
			position.x = newPosition.x;
		}
		if (keyRight) {
			float angle = rotation.y + 90;
			Vector3f newPosition = new Vector3f(position);
			float oblique = (walkingSpeed * 0.0002f) * delta;
			float adjacent = oblique * (float) Math.cos(Math.toRadians(angle));
			float opposite = (float) (Math.sin(Math.toRadians(angle)) * oblique);
			newPosition.z += adjacent;
			newPosition.x -= opposite;
			position.z = newPosition.z;
			position.x = newPosition.x;
		}
		if(jump)
		{
			
		}
		if (flyUp) {
			double newPositionY = (walkingSpeed * 0.0002) * delta;
			position.y -= newPositionY;
		}
		if (flyDown) {
			double newPositionY = (walkingSpeed * 0.0002) * delta;
			position.y += newPositionY;
		}
		if (moveFaster) {
			walkingSpeed /= 4f;
		}
		if (moveSlower) {
			walkingSpeed *= 10f;
		}
		while (Mouse.next()) {
			if (Mouse.isButtonDown(0)) {
				Mouse.setGrabbed(true);
			}
			if (Mouse.isButtonDown(1)) {
				Mouse.setGrabbed(false);
			}

		}
		while (Keyboard.next()) {
			if (Keyboard.isKeyDown(Keyboard.KEY_C)) {
				position = new Vector3f(0, 0, 0);
				rotation = new Vector3f(0, 0, 0);
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_O)) {
				mouseSpeed += 1;
				System.out.println("Mouse speed changed to " + mouseSpeed + ".");
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_L)) {
				if (mouseSpeed - 1 > 0) {
					mouseSpeed -= 1;
					System.out.println("Mouse speed changed to " + mouseSpeed + ".");
				}
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_Q)) {
				System.out.println("Walking speed changed to " + walkingSpeed + ".");
				walkingSpeed += 1;
			}
			if (Keyboard.isKeyDown(Keyboard.KEY_Z)) {
				System.out.println("Walking speed changed to " + walkingSpeed + ".");
				walkingSpeed -= 1;
			}
		}
		
		float mouseDX = Mouse.getDX() * mouseSpeed * 0.16f;
        float mouseDY = Mouse.getDY() * mouseSpeed * 0.16f;
        if (rotation.y + mouseDX >= 360) {
            rotation.y = rotation.y + mouseDX - 360;
        } else if (rotation.y + mouseDX < 0) {
            rotation.y = 360 - rotation.y + mouseDX;
        } else {
            rotation.y += mouseDX;
        }
        if (rotation.x - mouseDY >= MAX_LOOK_DOWN && rotation.x - mouseDY <= MAX_LOOK_UP) {
            rotation.x += -mouseDY;
        } else if (rotation.x - mouseDY < MAX_LOOK_DOWN) {
            rotation.x = MAX_LOOK_DOWN;
        } else if (rotation.x - mouseDY > MAX_LOOK_UP) {
            rotation.x = MAX_LOOK_UP;
        }
	}

	private int getDelta() {
		//
		long currentTime = getTime();
		int delta = (int) (currentTime - lastFrame);
		lastFrame = getTime();
		return delta;
	}

	private long getTime() {
		return (Sys.getTime() * 1000) / Sys.getTimerResolution();
	}
}
